package com.hzz.task;

import com.hzz.api.patrol.IInspectionPlanService;
import com.hzz.api.patrol.IPatrolTaskService;
import com.hzz.api.river.IRiverInfoService;
import com.hzz.dao.user.IUserDao;
import com.hzz.dto.patrol.InspectionPlanDto;
import com.hzz.dto.patrol.PatrolTaskDto;
import com.hzz.dto.river.RiverInfoDto;
import com.hzz.entity.user.User;
import com.hzz.framework.util.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.List;

@Component
@EnableTransactionManagement
@Slf4j
public class InspectionPlanTask {
    // 巡查周期
    private final static String YEAR = "年";

    private final static String MONTH = "月";

    private final static String WEEK = "周";

    // 等级
    // private final static String PROVINCE = "省级";
    // private final static String CITY = "市级";
    // private final static String COUNTY = "县级";
    // private final static String STREET = "乡镇级";
    // private final static String VILLAGE = "村级";

    // 巡查人员类别
    // private final static String HZ = "河长";
    // private final static String XCY = "巡查员";
    @Autowired
    private IRiverInfoService riverInfoService;

    @Autowired
    IInspectionPlanService planService;

    @Autowired
    IUserDao userDao;

    @Autowired
    IPatrolTaskService patrolTaskService;

    private List<RiverInfoDto> rivers;

//    /** 河长 **/
//    private ConcurrentHashMap<String, User> riverManMap = new ConcurrentHashMap<>();

    @Scheduled(cron = "0 0 3 * * ?") // 每天3点
    // @Scheduled(cron = "0 0/1 * * * ?") // 每天3点
    public void task() {
        log.info("InspectionPlanTask..进入..");
        Long begin = System.currentTimeMillis();
        try {
            synchronized (this) {
                log.info("InspectionPlanTask..now..", begin);
                // 查询所有巡查计划
                List<InspectionPlanDto> plans = planService.findDataIsList(null);
                rivers = riverInfoService.findDataIsList(new RiverInfoDto());
                User param = new User();
                // 1代表河长
                param.setTypes(CommonConstant.TYPES_各河长);
//            List<User> users = (List<User>) userDao.findDataIsList(param);
//            users.forEach(user -> {
//                if (user.getRiverId() != null) {
//                    String[] riverIds = user.getRiverId().split(",");
//                    for (String riverId : riverIds) {
//                        riverManMap.put(riverId + "", user);
//                    }
//                }
//            });
                // 遍历计划
                plans.forEach(plan -> {
                    try {
                        createPatrolTask(plan);
                    } catch (Exception e) {
                        log.error("系统生成常规巡查任务异常 .." + plan.toString());
                        throw new RuntimeException(e);
                    }
                });
            }
        } catch (Exception e) {
            log.error("巡查计划自动生成常规巡查任务异常 ..", e);
            return;
        }
        Long end = System.currentTimeMillis();
        log.info("InspectionPlanTask..结束..消耗时间{}", end - begin);
    }

    /**
     * 根据计划自动生成常规巡查任务
     * @param plan InspectionPlanDto 巡查计划
     */
    @Transactional
    void createPatrolTask(InspectionPlanDto plan) throws Exception {
        if (plan.getCycle().equals(YEAR)) {// 年计划
            yearTask(plan);
        } else if (plan.getCycle().equals(MONTH)) {// 月计划
            monthTask(plan);
        } else if (plan.getCycle().equals(WEEK)) {// 周计划
            weekTask(plan);
        }
    }

    /**
     * 年任务生成
     * @param plan
     */
    private void yearTask(InspectionPlanDto plan) throws Exception {
        // 获取任务时间
        String[] taskTime = plan.getTaskTime().split(";");// MM-dd hh:mm:ss,MM-dd hh:mm:ss;MM-dd hh:mm:ss,MM-dd hh:mm:ss
        if (taskTime.length == Integer.valueOf(plan.getTimes())) {// 验证时间数组是否和任务条数相等，一个任务对应一个开始结束时间
            for (int i = 0; i < taskTime.length; i++) {
                // 处理任务时间 MM-dd hh:mm:ss,MM-dd hh:mm:ss
                String start = taskTime[i].split(",")[0];
                String end = taskTime[i].split(",")[1];
                // 处理开始时间
                Calendar startCalendar = Calendar.getInstance();
                // 月
                startCalendar.set(Calendar.MONTH, Integer.valueOf(start.split("-")[0]));
                startCalendar.add(Calendar.MONTH, -1);// 月是从0开始，需要根据参数减一
                // 日
                startCalendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(start.split(" ")[0].split("-")[1]));
                // 时
                startCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(start.split(" ")[1].split(":")[0]));
                // 分
                startCalendar.set(Calendar.MINUTE, Integer.valueOf(start.split(" ")[1].split(":")[1]));
                // 秒
                startCalendar.set(Calendar.SECOND, Integer.valueOf(start.split(" ")[1].split(":")[2]));
                // 毫秒
                startCalendar.set(Calendar.MILLISECOND, 0);
                // 处理结束时间 MM-dd hh:mm:ss
                Calendar endCalendar = Calendar.getInstance();
                // 月
                endCalendar.set(Calendar.MONTH, Integer.valueOf(end.split("-")[0]));
                endCalendar.add(Calendar.MONTH, -1);// 月是从0开始，需要根据参数减一
                // 日
                endCalendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(end.split(" ")[0].split("-")[1]));
                // 时
                endCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(end.split(" ")[1].split(":")[0]));
                // 分
                endCalendar.set(Calendar.MINUTE, Integer.valueOf(end.split(" ")[1].split(":")[1]));
                // 秒
                endCalendar.set(Calendar.SECOND, Integer.valueOf(end.split(" ")[1].split(":")[2]));
                // 毫秒
                endCalendar.set(Calendar.MILLISECOND, 0);
                for (RiverInfoDto river : rivers) {
                    if (plan.getLevel().equals(river.getLevel())) {
                        PatrolTaskDto task = new PatrolTaskDto();
                        task.setStartTime(startCalendar.getTime());
                        task.setEndTime(endCalendar.getTime());
                        task.setCreatorLevel(plan.getLevel());
                        // task.setRiverCourseCode(plan.getRiverCourseCode());
                        task.setRiverCourseCode(river.getId().toString());
                        task.setRiverCourseName(river.getName());
                        task.setAreaIds(river.getAreaIds());
                        task.setAreaNames(river.getAreaNames());
                        task.setPac(river.getPac());
//                        // 根据河道id获取河长
//                        User riverMan = riverManMap.get(river.getId());
//                        if (riverMan != null) {
//                            task.setExecutorName(riverMan.getName());
//                            task.setExecutorAccount(riverMan.getAccount());
//                        }
                        task.setTaskType("常规任务");
                        task.setTarget("本级河道");
                        task.setExecutorRole(plan.getPersonType());
                        task.setTaskContent("常规任务");
                        task.setCreateId(1L);// 系统生成，创建人id暂时用admin
                        task.setMemo("系统生成");
                        List tasks = patrolTaskService.getList(task);
                        task.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_未巡查);
                        // 查询是否已经生成，没有生成记录就创建此任务
                        if (tasks == null || tasks.size() == 0) {
                            patrolTaskService.saveOrUpdateData(task);
                        }
                    }
                }
            }
        }
    }

    /**
     * 月任务生成
     * @param plan
     */
    private void monthTask(InspectionPlanDto plan) throws Exception {
        String[] taskTime = plan.getTaskTime().split(";");// dd hh:mm:ss,dd hh:mm:ss;dd hh:mm:ss,dd hh:mm:ss
        if (taskTime.length == Integer.valueOf(plan.getTimes())) {
            for (int i = 0; i < taskTime.length; i++) {
                // 处理任务时间 dd hh:mm:ss,dd hh:mm:ss
                String start = taskTime[i].split(",")[0];
                String end = taskTime[i].split(",")[1];
                // 处理开始时间 dd hh:mm:ss
                Calendar startCalendar = Calendar.getInstance();
                // 日
                startCalendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(start.split(" ")[0]));
                // 时
                startCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(start.split(" ")[1].split(":")[0]));
                // 分
                startCalendar.set(Calendar.MINUTE, Integer.valueOf(start.split(" ")[1].split(":")[1]));
                // 秒
                startCalendar.set(Calendar.SECOND, Integer.valueOf(start.split(" ")[1].split(":")[2]));
                // 毫秒
                startCalendar.set(Calendar.MILLISECOND, 0);
                // 处理结束时间 dd hh:mm:ss
                Calendar endCalendar = Calendar.getInstance();
                // 日
                endCalendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(end.split(" ")[0]));
                // 时
                endCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(end.split(" ")[1].split(":")[0]));
                // 分
                endCalendar.set(Calendar.MINUTE, Integer.valueOf(end.split(" ")[1].split(":")[1]));
                // 秒
                endCalendar.set(Calendar.SECOND, Integer.valueOf(end.split(" ")[1].split(":")[2]));
                // 毫秒
                endCalendar.set(Calendar.MILLISECOND, 0);
                for (RiverInfoDto river : rivers) {
                    if (plan.getLevel().equals(river.getLevel())) {
                        PatrolTaskDto task = new PatrolTaskDto();
                        task.setStartTime(startCalendar.getTime());
                        task.setEndTime(endCalendar.getTime());
                        task.setCreatorLevel(plan.getLevel());
                        // task.setRiverCourseCode(plan.getRiverCourseCode());
                        task.setRiverCourseCode(river.getId().toString());
                        task.setRiverCourseName(river.getName());
                        task.setAreaIds(river.getAreaIds());
                        task.setAreaNames(river.getAreaNames());
                        task.setPac(river.getPac());
//                        // 根据河道id获取河长
//                        User riverMan = riverManMap.get(river.getId());
//                        if (riverMan != null) {
//                            task.setExecutorName(riverMan.getName());
//                            task.setExecutorAccount(riverMan.getAccount());
//                        }
                        task.setTaskType("常规任务");
                        List tasks = patrolTaskService.getList(task);
                        task.setTarget("本级河道");
                        task.setExecutorRole(plan.getPersonType());
                        task.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_未巡查);
                        task.setTaskContent("常规任务");
                        task.setCreateId(1L);// 系统生成，创建人id暂时用admin
                        task.setMemo("系统生成");
                        // 查询是否已经生成，没有生成记录就创建此任务
                        if (tasks == null || tasks.size() == 0) {
                            patrolTaskService.saveOrUpdateData(task);
                        }
                    }
                }
                // PatrolTaskDto task = new PatrolTaskDto();
                // task.setStartTime(startCalendar.getTime());
                // task.setEndTime(endCalendar.getTime());
                // task.setCreatorLevel(plan.getLevel());
                // task.setRiverCourseCode(plan.getRiverCourseCode());
                // task.setRiverCourseName(river.getName());
                // task.setAreaIds(river.getAreaIds());
                // task.setAreaNames(river.getAreaNames());
                // task.setPac(river.getPac());
                // task.setTaskType("常规任务");
                // task.setTarget("本级河道");
                // task.setExecutorRole(plan.getPersonType());
                // task.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_未巡查);
                // task.setTaskContent("常规任务");
                // task.setCreateId(1L);// 系统生成，创建人id暂时用admin
                // task.setMemo("系统生成");
                // // 查询是否已经生成，没有生成记录就创建此任务
                // List tasks = patrolTaskService.findListByParam(task);
                // if (tasks == null || tasks.size() == 0) {
                // patrolTaskService.saveOrUpdateData(task);
                // }
            }
        }
    }

    /**
     * 周任务生成
     * @param plan
     */
    private void weekTask(InspectionPlanDto plan) throws Exception {
        String[] taskTime = plan.getTaskTime().split(";");// w hh:mm:ss,w hh:mm:ss;w hh:mm:ss,w hh:mm:ss
        if (taskTime.length == Integer.valueOf(plan.getTimes())) {
            for (int i = 0; i < taskTime.length; i++) {
                // 处理任务时间 w hh:mm:ss (w表示星期几)
                String start = taskTime[i].split(",")[0];
                String end = taskTime[i].split(",")[1];
                // 处理开始时间
                Calendar startCalendar = Calendar.getInstance();
                // 日
                startCalendar.set(Calendar.DAY_OF_WEEK, Integer.valueOf(start.split(" ")[0]));
                startCalendar.add(Calendar.DATE, 1);
                // 时
                startCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(start.split(" ")[1].split(":")[0]));
                // 分
                startCalendar.set(Calendar.MINUTE, Integer.valueOf(start.split(" ")[1].split(":")[1]));
                // 秒
                startCalendar.set(Calendar.SECOND, Integer.valueOf(start.split(" ")[1].split(":")[2]));
                // 毫秒
                startCalendar.set(Calendar.MILLISECOND, 0);
                // 处理结束时间 w hh:mm:ss (w表示星期几)
                Calendar endCalendar = Calendar.getInstance();
                // 日
                endCalendar.set(Calendar.DAY_OF_WEEK, Integer.valueOf(end.split(" ")[0]));
                endCalendar.add(Calendar.DATE, 1);
                // 时
                endCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(end.split(" ")[1].split(":")[0]));
                // 分
                endCalendar.set(Calendar.MINUTE, Integer.valueOf(end.split(" ")[1].split(":")[1]));
                // 秒
                endCalendar.set(Calendar.SECOND, Integer.valueOf(end.split(" ")[1].split(":")[2]));
                // 毫秒
                endCalendar.set(Calendar.MILLISECOND, 0);
                for (RiverInfoDto river : rivers) {
                    if (plan.getLevel().equals(river.getLevel())) {
                        PatrolTaskDto task = new PatrolTaskDto();
                        task.setStartTime(startCalendar.getTime());
                        task.setEndTime(endCalendar.getTime());
                        task.setCreatorLevel(plan.getLevel());
                        // task.setRiverCourseCode(plan.getRiverCourseCode());
                        task.setRiverCourseCode(river.getId().toString());
                        task.setRiverCourseName(river.getName());
                        task.setAreaIds(river.getAreaIds());
                        task.setAreaNames(river.getAreaNames());
                        task.setPac(river.getPac());
//                        // 根据河道id获取河长
//                        User riverMan = riverManMap.get(river.getId());
//                        if (riverMan != null) {
//                            task.setExecutorName(riverMan.getName());
//                            task.setExecutorAccount(riverMan.getAccount());
//                        }
                        task.setTaskType("常规任务");
                        List tasks = patrolTaskService.getList(task);
                        task.setTarget("本级河道");
                        task.setExecutorRole(plan.getPersonType());
                        task.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_未巡查);
                        task.setTaskContent("常规任务");
                        task.setCreateId(1L);// 系统生成，创建人id暂时用admin
                        task.setMemo("系统生成");
                        // 查询是否已经生成，没有生成记录就创建此任务
                        if (tasks == null || tasks.size() == 0) {
                            patrolTaskService.saveOrUpdateData(task);
                        }
                        // 生成下一周的任务
                        task = new PatrolTaskDto();
                        startCalendar.add(Calendar.WEEK_OF_YEAR, 1);
                        endCalendar.add(Calendar.WEEK_OF_YEAR, 1);
                        task.setStartTime(startCalendar.getTime());
                        task.setEndTime(endCalendar.getTime());
                        task.setCreatorLevel(plan.getLevel());
                        // task.setRiverCourseCode(plan.getRiverCourseCode());
                        task.setRiverCourseCode(river.getId().toString());
                        task.setRiverCourseName(river.getName());
                        task.setAreaIds(river.getAreaIds());
                        task.setAreaNames(river.getAreaNames());
                        task.setPac(river.getPac());
//                        if (riverMan != null) {
//                            task.setExecutorName(riverMan.getName());
//                            task.setExecutorAccount(riverMan.getAccount());
//                        }
                        task.setTaskType("常规任务");
                        List tasksNext = patrolTaskService.getList(task);
                        task.setTarget("本级河道");
                        task.setExecutorRole(plan.getPersonType());
                        task.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_未巡查);
                        task.setTaskContent("常规任务");
                        task.setCreateId(1L);// 系统生成，创建人id暂时用admin
                        task.setMemo("系统生成");
                        if (tasksNext == null || tasksNext.size() == 0) {
                            patrolTaskService.saveOrUpdateData(task);
                        }
                        // 把日期还原到本周
                        startCalendar.add(Calendar.WEEK_OF_YEAR, -1);
                        endCalendar.add(Calendar.WEEK_OF_YEAR, -1);
                    }
                }
            }
        }
    }
}
